﻿using AvaloniaDevice.Common.Services;
using AvaloniaDevice.Common.WIFI;
using AvaloniaLinux.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

//[assembly: RuntimeDependency(typeof(LinuxWifiService))]

namespace AvaloniaLinux.Core
{
    public class LinuxWifiService : IWifiService
    {
        private const string NetworkManagerCommand = "nmcli";

        public bool IsWifiEnabled()
        {
            try
            {
                var output = ExecuteCommand($"{NetworkManagerCommand} radio wifi");
                return output.Contains("enabled");
            }
            catch
            {
                return false;
            }
        }

        public async Task SetWifiEnabled(bool enabled)
        {
            string status = enabled ? "on" : "off";
            await ExecuteCommandAsync($"{NetworkManagerCommand} radio wifi {status}");
            await Task.Delay(1000);
        }

        public async Task<List<WifiInfo>> GetAvailableNetworks()
        {
            var result = new List<WifiInfo>();

            if (!IsWifiEnabled())
                return result;

            try
            {
                // 扫描网络
                await ExecuteCommandAsync($"{NetworkManagerCommand} device wifi rescan");
                await Task.Delay(2000); // 等待扫描完成

                // 获取扫描结果
                string output = await ExecuteCommandAsync($"{NetworkManagerCommand} device wifi list");

                // 解析结果
                string[] lines = output.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
                if (lines.Length <= 1) // 第一行是标题
                    return result;

                foreach (var line in lines.Skip(1))
                {
                    var parts = line.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length < 5)
                        continue;

                    // 信号强度(0-100)
                    if (!int.TryParse(parts[0].Trim('%'), out int signalStrength))
                        continue;

                    // 加密类型
                    string encryptionType = parts[1];
                    bool isEncrypted = encryptionType != "--";

                    // SSID可能包含空格，所以需要特殊处理
                    int ssidStartIndex = isEncrypted ? 4 : 3;
                    string ssid = string.Join(" ", parts.Skip(ssidStartIndex));

                    result.Add(new WifiInfo
                    {
                        Ssid = ssid,
                        Bssid = parts[2],
                        SignalStrength = signalStrength,
                        IsEncrypted = isEncrypted,
                        EncryptionType = isEncrypted ? encryptionType : "开放",
                        IsConnected = line.Contains("*") // 带*号表示已连接
                    });
                }

                return result;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"扫描WiFi失败: {ex.Message}");
                return result;
            }
        }

        public async Task<bool> ConnectToWifi(string ssid, string password = null)
        {
            try
            {
                string command;

                if (string.IsNullOrEmpty(password))
                {
                    // 连接开放网络
                    command = $"{NetworkManagerCommand} device wifi connect \"{ssid}\"";
                }
                else
                {
                    // 连接加密网络
                    command = $"{NetworkManagerCommand} device wifi connect \"{ssid}\" password \"{password}\"";
                }

                string result = await ExecuteCommandAsync(command);
                return result.Contains("successfully activated");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"连接WiFi失败: {ex.Message}");
                return false;
            }
        }

        public async Task<bool> DisconnectFromWifi(string ssid)
        {
            try
            {
                // 获取当前连接的网络ID
                string connectionOutput = await ExecuteCommandAsync($"{NetworkManagerCommand} connection show --active");
                var lines = connectionOutput.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (var line in lines.Skip(1))
                {
                    var parts = line.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length >= 1 && parts[0].Contains(ssid.Replace(" ", "_")))
                    {
                        string disconnectResult = await ExecuteCommandAsync($"{NetworkManagerCommand} connection down id {parts[0]}");
                        return disconnectResult.Contains("successfully deactivated");
                    }
                }

                return false;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"断开WiFi失败: {ex.Message}");
                return false;
            }
        }

        public WifiInfo GetConnectedWifi()
        {
            try
            {
                string output = ExecuteCommand($"{NetworkManagerCommand} device wifi list");
                string[] lines = output.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (var line in lines.Skip(1))
                {
                    if (line.Contains("*")) // 带*号表示已连接
                    {
                        var parts = line.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        if (parts.Length < 5)
                            continue;

                        if (!int.TryParse(parts[0].Trim('%'), out int signalStrength))
                            continue;

                        string encryptionType = parts[1];
                        bool isEncrypted = encryptionType != "--";

                        int ssidStartIndex = isEncrypted ? 4 : 3;
                        string ssid = string.Join(" ", parts.Skip(ssidStartIndex));

                        return new WifiInfo
                        {
                            Ssid = ssid,
                            Bssid = parts[2],
                            SignalStrength = signalStrength,
                            IsEncrypted = isEncrypted,
                            EncryptionType = isEncrypted ? encryptionType : "开放",
                            IsConnected = true
                        };
                    }
                }

                return null;
            }
            catch
            {
                return null;
            }
        }

        public bool IsSupported
        {
            get
            {
                try
                {
                    // 检查nmcli是否可用
                    ExecuteCommand($"{NetworkManagerCommand} --version");
                    return true;
                }
                catch
                {
                    return false;
                }
            }
        }

        public string PlatformRestrictions => "需要NetworkManager(nmcli)支持，可能需要管理员权限";

        // 同步执行命令
        private string ExecuteCommand(string command)
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "/bin/bash",
                    Arguments = $"-c \"{command}\"",
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                }
            };

            process.Start();
            string output = process.StandardOutput.ReadToEnd();
            string error = process.StandardError.ReadToEnd();
            process.WaitForExit();

            if (!string.IsNullOrEmpty(error))
                throw new Exception(error);

            return output;
        }

        // 异步执行命令
        private async Task<string> ExecuteCommandAsync(string command)
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "/bin/bash",
                    Arguments = $"-c \"{command}\"",
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                }
            };

            process.Start();

            // 异步读取输出
            string output = await process.StandardOutput.ReadToEndAsync();
            string error = await process.StandardError.ReadToEndAsync();

            await process.WaitForExitAsync();

            if (!string.IsNullOrEmpty(error))
                throw new Exception(error);

            return output;
        }
    }
}
